package com.jckj.core.util;

import com.jckj.core.annotation.LogTitle;
import com.jckj.core.entity.SysLog;
import com.jckj.core.service.SysLogService;
import com.jckj.core.vos.LoginUserVo;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Calendar;

/**
 * <p>
 *     日志工具类
 * </p>
 * @author liuzhiyuan
 * @date 2018-01-08
 */
public class LogUtils {
    public static void saveLog(HttpServletRequest request, Object handler, Exception ex, String title){
        LoginUserVo user = UserUtils.getLoginUser();
        if (user != null && user.getId() != null){
            SysLog log = new SysLog();
            log.setId(StringUtils.genId());
            log.setTitle(title);
            log.setType(ex == null ? LogType.TYPE_ACCESS.getTypeValue() : LogType.TYPE_EXCEPTION.getTypeValue());
            log.setIpAddress(StringUtils.getRemoteAddr(request));
            log.setUserAgent(request.getHeader("user-agent"));
            log.setRequestUri(request.getRequestURI());
            log.setParams(StringUtils.map2String(request.getParameterMap()));
            log.setMethod(request.getMethod());
            log.setCreateBy(user.getLoginName());
            log.setCreateTime(Calendar.getInstance().getTime());
            // 异步保存日志
            new SaveLogThread(log, handler, ex).start();
        }
    }

    public static class SaveLogThread extends Thread{

        private SysLog log;
        private Object handler;
        private Exception ex;

        public SaveLogThread(SysLog log, Object handler, Exception ex){
            super(SaveLogThread.class.getSimpleName());
            this.log = log;
            this.handler = handler;
            this.ex = ex;
        }

        @Override
        public void run() {
            // 获取日志标题
            if (StringUtils.isBlank(log.getTitle())){
                if(handler instanceof  HandlerMethod) {
                    Method m = ((HandlerMethod) handler).getMethod();
                    LogTitle logTitle = m.getAnnotation(LogTitle.class);
                    if (logTitle != null) {
                        log.setTitle(logTitle.title());
                    }
                }
            }
            // 如果有异常，设置异常信息
            log.setException(ExceptionUtils.getStackTraceAsString(ex));
            // 如果无标题并无异常日志，则不保存信息
            if (StringUtils.isBlank(log.getTitle()) && StringUtils.isBlank(log.getException())){
                return;
            }
            SpringContextHolder.getBean(SysLogService.class).insert(log);
        }
    }
}
